package com.koron.standard.deviceClasssify.excel;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.CellExtra;
import com.koron.standard.deviceClasssify.bean.excel.TypeExcel;
import com.koron.standard.excel.ExcelError;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
 * 1. 编码重复性检查
 * 2. 编码格式检查
 * 3. 父类编码是否存在检查
 * @author jzp
 * @since 2022/5/11
 */
@Slf4j
public class TypeCodeCheckExcelListener extends AnalysisEventListener<TypeExcel> {

    private final Map<Integer, ExcelError> excelErrors = new HashMap<>();
    private final Set<String> allCode;

    public TypeCodeCheckExcelListener(Set<String> allCode) {
        this.allCode = allCode;
    }

    @Override
    public void invoke(TypeExcel data, AnalysisContext context) {
        String code = data.getCode();
        if (code == null) {
            return;
        }
        Integer rowIndex = context.readRowHolder().getRowIndex();
        // 编码重复性检查
        if (allCode.contains(code)) {
            ExcelError excelError = new ExcelError(rowIndex, 0, "编码重复");
            excelErrors.put(rowIndex, excelError);
            log.error("编码重复：{}", excelErrors);
        }
        // 编码格式检查
        if (code.length() % 3 != 0) {
            ExcelError excelError = excelErrors.get(rowIndex);
            if (excelError == null) {
                excelError = new ExcelError(rowIndex, 0, "编码格式错误（长度必须是3的倍数）");
                excelErrors.put(rowIndex, excelError);
            } else {
                excelError.setComment(excelError.getComment() + "；编码格式错误（长度必须是3的倍数）");
            }
            log.error("编码格式错误：{}", excelErrors);
        } else {
            // 父类编码是否存在检查
            String parentCode = code.substring(0, code.length() - 3);
            // 如果父类编码不为空且不存在
            if (StrUtil.isNotEmpty(parentCode) && !allCode.contains(parentCode)) {
                ExcelError excelError = excelErrors.get(rowIndex);
                if (excelError == null) {
                    excelError = new ExcelError(rowIndex, 0, "该编码的父类编码找不到");
                    excelErrors.put(rowIndex, excelError);
                } else {
                    excelError.setComment(excelError.getComment() + "；该编码的父类编码找不到");
                }
                log.error("父类编码不为空且不存在：{}", excelErrors);
            }
        }
        allCode.add(code);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
    }

    @Override
    public void extra(CellExtra extra, AnalysisContext context) {
        // 如果不是第一列，或者当前行不在错误编码行中
        if (extra.getFirstColumnIndex() != 0 || !excelErrors.containsKey(extra.getFirstRowIndex())) {
            return;
        }
        Integer firstRowIndex = extra.getFirstRowIndex();
        Integer lastRowIndex = extra.getLastRowIndex();
        ExcelError excelError = excelErrors.get(firstRowIndex);
        excelError.setRowStep(lastRowIndex - firstRowIndex);
    }

    public List<ExcelError> getExcelErrors() {
        return new ArrayList<>(excelErrors.values());
    }
}
